package com.cndw.kungfu.model.activity;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ScheduledFuture;

import com.cndw.commons.util.BlankUtils;
import com.cndw.kungfu.config.Constants;
import com.cndw.kungfu.config.ConstantsModel;
import com.cndw.kungfu.config.ConstantsRadio;
import com.cndw.kungfu.domain.Player;
import com.cndw.kungfu.ext.TimeProcesser;
import com.cndw.kungfu.model.Context;
import com.cndw.kungfu.model.general.ModeExpConfig;
import com.cndw.kungfu.vo.EventNotice;
import com.cndw.kungfu.vo.PlayerReceiveVO;

/**
 * 塞外对象
 * 
 * 
 * @author <a href="mailto:whz-work@163.com">汪洪州</a>
 * 
 * @since 1.0 Create on 2011-9-21
 */
/**
 * 
 * 
 * @author <a href="mailto:whz-work@163.com">汪洪州</a>
 * 
 * @since 1.0 Create on 2011-9-22
 */
public class ModeSceneWall {


	/**
	 * 玩家id
	 */
	private long playerId;

	/**
	 * 进入的场景Id
	 */
	private int sceneId;

	/**
	 * 塞外结束任务
	 */
	private static ScheduledFuture<?> activeEndTask;

	/**
	 * 刺杀该玩家的列表
	 */
	private Map<Long, Integer> killMap = new HashMap<Long, Integer>();

	/**
	 * 进入时间，用来排序
	 */
	private int intoTime;

	/**
	 * 最多刺杀次数
	 */
	private static final int killMaxCounts = 5;

	/**
	 * 参加塞外活动的玩家
	 */
	private static final Map<Long, ModeSceneWall> players = new ConcurrentHashMap<Long, ModeSceneWall>();

	private ModeSceneWall(long playerId, int sceneId) {
		this.playerId = playerId;
		this.sceneId = sceneId;
		this.intoTime = TimeProcesser.getUnixTime();
	}

	/**
	 * 增加塞外玩家
	 * 
	 * @param playerId
	 * @return
	 */
	public static final void addPlayer(Player player, int sceneId) {
		if (!players.containsKey(player.getPlayerId())) {
			players.put(player.getPlayerId(), new ModeSceneWall(player.getPlayerId(), sceneId));
		}
	}

	/**
	 * 删除玩家
	 * 
	 * @param playerId
	 */
	public static final void removePlayer(Player player) {
		players.remove(player.getPlayerId());
	}

	/**
	 * 获取玩家塞外对象
	 * 
	 * @param playerId
	 * @return
	 */
	public static final ModeSceneWall getPlayer(long playerId) {
		return players.get(playerId);
	}
	public static final boolean containsPlayer(long playerId){
		return players.containsKey(playerId);
	}

	/**
	 * 获取塞外所有场景的玩家
	 * 
	 * @return
	 */
	public static Set<Long> getAllPlayerIds() {
		return players.keySet();
	}

	public static void checkWallEndTask() {
		if (activeEndTask == null) {
			synchronized (ModeSceneWall.class) {
				if (activeEndTask == null) {
					activeEndTask = Context.getTimerServer().scheduleMilliSeconds(new Runnable() {
						@Override
						public void run() {
							EventNotice eventNotice = new EventNotice(ConstantsRadio.wall, ConstantsRadio.wall_end);
							eventNotice.broadcast(players.keySet());
						}
					}, Context.getSceneServer().getWallEndTime().getTime() - System.currentTimeMillis());
				}
			}
		}
	}

	/**
	 * 检查用户是否是一个活动的状态
	 */
	public boolean checkPlayerActiveStatus() {
		return !Context.getPlayerServer().getByPlayerId(getPlayerId()).stateContains(Constants.playerState16_banish);
	}

	/**
	 * 刺杀玩家
	 * 
	 * @param status
	 *            死亡玩家的状态
	 */
	public static void killPlayer(int status, List<Player> winer, final List<Player> lost) {

		Map<Long, Integer> playerExp = new HashMap<Long, Integer>();
		for (Player player : winer) {
			player.stateRemove(status);
			playerExp.put(player.getPlayerId(), 0);
			Context.getPlayerServer().broadcaseState(player);
		}

		for (Player target : lost) {
			target.stateRemove(status);
			target.stateAdd(Constants.playerState16_banish);
			Context.getPlayerServer().broadcaseState(target);
		}

		Context.getTimerServer().scheduleSeconds(new Runnable() {
			@Override
			public void run() {
				for (Player target : lost) {
					target.stateRemove(Constants.playerState16_banish);
					Context.getPlayerServer().broadcaseState(target);
				}
			}
		}, ConstantsModel.banishTimeLimit);

		for (Player target : lost) {
			List<Long> playerIds = new ArrayList<Long>(5); // 能获得经验的玩家
			ModeSceneWall wall = ModeSceneWall.getPlayer(target.getPlayerId());
			if (!BlankUtils.isBlank(wall)) {
				for (Player player : winer) {
					if (!wall.checkKillCounts(player.getPlayerId()) && !(player.getLevel() == Constants.playerMaxLevel)) { // 没刺杀三次，且没满100级则有经验
						playerIds.add(player.getPlayerId());
					}
				}
			}
			
			int exp = getExp(target);
			for (Long playerId : playerIds) {
				int addExp = exp / playerIds.size();
				Player player = Context.getPlayerServer().getByPlayerId(playerId);
				player.alterExp(addExp);
				playerExp.put(playerId, playerExp.get(playerId).intValue() + addExp);
				player.commitSync();
			}
		}

		for (Long playerId : playerExp.keySet()) {
			int exp = playerExp.get(playerId);
			if (exp > 0) {
				Context.getPlayerServer().receive(PlayerReceiveVO.RECEIVE_EXP, exp, playerId);
			}
		}
	}

	/**
	 * 检查玩家被指定玩家是否杀了指定次数
	 * 
	 * @param playerId
	 * @return
	 */
	public synchronized boolean checkKillCounts(Long playerId) {
		if (killMap.containsKey(playerId)) {
			int counts = killMap.get(playerId);
			if (counts >= killMaxCounts) {
				return true;
			} else {
				killMap.put(playerId, ++counts);
			}
		} else {
			killMap.put(playerId, 1);
		}

		return false;
	}

	/**
	 * 获得的经验
	 * 
	 * @param player
	 * @return
	 */
	public static int getExp(Player player) {
		return ModeExpConfig.getOnlineExp().get(Integer.valueOf(player.getLevel())) * 25;
	}

	public long getPlayerId() {
		return playerId;
	}

	public void setPlayerId(long playerId) {
		this.playerId = playerId;
	}

	public int getIntoTime() {
		return intoTime;
	}

	public int getSceneId() {
		return sceneId;
	}

	public void setSceneId(int sceneId) {
		this.sceneId = sceneId;
	}

}
